﻿using System;
using System.Text;
using System.IO;

namespace CCodeTreeLib
{
    public class CodeInjector
    {
        public CodeInjector(string startString, string injectedCode, string endString)
        {
            StartString = startString;
            EndString = endString;
            Code = injectedCode;
        }

        public string Code { get; set; }

        public string EndString
        {
            get;
            set;
        }

        public string StartString
        {
            get;
            set;
        }

        public void WriteToFile(string path)
        {
            if (!File.Exists(path))
                throw new IOException("could not find file at path " + path);
            string tmpPath = Path.GetTempFileName();
            byte[] strtBytes = Encoding.Default.GetBytes(StartString);
            byte[] endBytes = Encoding.Default.GetBytes(EndString);
            byte[] codeBytes = Encoding.Default.GetBytes(Code);
            bool complete;
            using (var sr = new StreamReader(path))
            {
                using (var sw = new StreamWriter(tmpPath))
                {
                    long startIndex = KnuthMorrisPratt.ReadTo(strtBytes, sr.BaseStream, sw.BaseStream);
                    if (startIndex > -1)
                    {
                        long endIndex = KnuthMorrisPratt.ReadTo(endBytes, sr.BaseStream, null);
                        if (endIndex > -1)
                        {
                            sw.BaseStream.Write(codeBytes, 0, codeBytes.Length);
                            const int buffsz = 4096;
                            var b = new byte[buffsz];
                            int readbytes;
                            sr.BaseStream.Position = endIndex;
                            while ((readbytes = sr.BaseStream.Read(b, 0, buffsz)) > 0)
                                sw.BaseStream.Write(b, 0, readbytes);
                            complete = true;
                        }
                        else
                            throw new Exception("End string not found");
                    }
                    else
                        throw new Exception("Start string not found");
                }
            }
            if (complete)
            {
                if (File.Exists(path))
                    File.Delete(path );
                File.Move(tmpPath, path);
            }
        }
    }
}
